package com.cloud.idGene;

/**
 * @Author tangyuan2meicloud.com
 * @DATE 2021/7/8 10:11
 * @Desc
 * @Remarks
 */
public class SnowIdGene2 {
    //    0 41 5 5 12
    public static final long ROOM_BIT = 5L;
    public static final long MAX_ROOM_NUM = -1 ^ (-1 << 5L);
    public static final long COM_BIT = 5L;
    public static final long MAX_COM_NUM = -1 ^ (-1 << 5L);
    public static final long SEQ_BIT = 12L;
    public static final long MAX_SEQ_NUM = -1 ^ (-1 << 12L);

    long roomNum;
    long comNum;
    long seq;

    long interval = 1625710777029L;
    long lastGeneTime = -1L;

    public static void main(String[] args) {
        SnowIdGene2 snowIdGene2 = new SnowIdGene2(2, 3, 1);
        for (int i = 0; i < 100; i++) {

            System.out.println(snowIdGene2.nextId());
        }

    }

    public SnowIdGene2(long roomNum, long comNum, long seq) {
        this.roomNum = roomNum;
        this.comNum = comNum;
        this.seq = seq;
    }

    public synchronized long nextId() {
        long now = System.currentTimeMillis();
        if (lastGeneTime > now) {
            throw new RuntimeException("时间错误");
        } else if (lastGeneTime == now) {
            seq = seq + 1 & MAX_SEQ_NUM;
            if (seq == 0) {
                now = toNextTimeStamp(now);
                seq = now % 2;
            }
        } else {
            seq = now % 2;
        }
        lastGeneTime = now;
        return (now - interval) << (ROOM_BIT + COM_BIT + SEQ_BIT) | (roomNum) << (ROOM_BIT + COM_BIT + SEQ_BIT) | (comNum) << (SEQ_BIT) | seq;
    }

    private long toNextTimeStamp(long now) {
        long l = System.currentTimeMillis();
        while (now <= l) {
            l = System.currentTimeMillis();
        }
        return l;
    }
}
